﻿using Newtonsoft.Json;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZoneLineNew.Common;
using ZoneLineNew.Enums;
using ZoneLineNew.Models.Entity.Template;
using ZoneLineNew.Models.PrintResult;
using ZoneLineNew.Models.StationConfig;
using ZoneLineNew.Models.StationResult.QOPStation;
using ZoneLineNew.Services.DB;
using ZoneLineNew.Services.Print;

namespace ZoneLineNew.Services.Station.QOPStation {
    /// <summary>
    /// 上支撑螺母拧紧工位(右)
    /// </summary>
    /// <remarks>
    /// <para>StationCode：OP580-2</para>
    /// <para>IP：192.168.10.105</para>
    /// </remarks>
    public class QOP050RStationService : WorkStationBaseService<QOP050RStationResult, QOP050RStationConfig> {
        
        public QOP050RStationService(
            IDbOperate<IFreeSqlMainContext> mainDbOperate,
            IEventAggregator eventAggregator,
            PrinterLabelService printerService
            ) : base(mainDbOperate, eventAggregator, printerService) {

            base.InitReSetAddr();
        }

        #region 查重功能

        private bool _repeatCheckSignal;
        /// <summary>
        /// 查重请求 1：触发 0：复位
        /// </summary>
        public bool RepeatCheckSignal {
            get { return _repeatCheckSignal; }
            protected set
            {
                SetProperty(ref _repeatCheckSignal, value);
            }
        }

        private string _scanQrCode1;
        /// <summary>
        /// 扫码1
        /// </summary>
        public string ScanQrCode1 {
            get { return _scanQrCode1; }
            set { _scanQrCode1 = value; base.RaisePropertyChanged(); }
        }

        private string _scanQrCode2;
        /// <summary>
        /// 扫码2
        /// </summary>
        public string ScanQrCode2 {
            get { return _scanQrCode2; }
            set { _scanQrCode2 = value; base.RaisePropertyChanged(); }
        }

        #endregion

        public override void DealData(byte[] content) {
            StationRecordData.AbsScanCode = GetPlcString(content, 280);
            //StationRecordData.NutScanCode = GetPlcString(content, 322);
            StationRecordData.PartType = GetPlcString(content, 1002);
            StationRecordData.Result = _client.ByteTransform.TransInt16(content, 1000).ToString().Equals("1") ? "OK" : "NG";
            StationRecordData.TightenTorque = _client.ByteTransform.TransSingle(content, 1016);
            StationRecordData.TightenAngle = _client.ByteTransform.TransSingle(content, 1020);
            StationRecordData.CycleTime = _client.ByteTransform.TransSingle(content, 1032);
            StationRecordData.ThreadLength = _client.ByteTransform.TransSingle(content, 1024);

            //批次追溯
            StationRecordData.LabelCapScanCode = _client.ReadString("DB1100.DBX0").Content;
            StationRecordData.DustCapScanCode = _client.ReadString("DB1100.DBX50").Content;
        }

        public override void DealWithCommonData(byte[] content) {
            Heart = _client.ByteTransform.TransInt16(content, 8) == (short)1;
            StartUploadCode = _client.ByteTransform.TransInt16(content, 6) == (Int16)1;
            StartUploadData = _client.ByteTransform.TransInt16(content, 10) == (Int16)1;

            HeartToPlc = _client.ReadInt16("DB1001.DBW0").Content == (Int16)1;
            EndUpLoadCode = _client.ReadInt16("DB1001.8").Content == (Int16)1;
            EndUpLoadData = _client.ReadInt16("DB1001.2").Content == (Int16)1;
            AllowWork = _client.ReadInt16("DB1001.8").Content;

            #region 查重功能 数据接收  第二个上传条码指令
            RepeatCheckSignal = _client.ReadInt16("DB99.100").Content == (Int16)1;
            ScanQrCode1 = _client.ReadString("DB99.0").Content;
            ScanQrCode2 = _client.ReadString("DB99.50").Content;
            #endregion
        }

        public override void DealWithSignal(string signalName) {

            if (signalName == nameof(StartUploadCode))
            {
                // todo 上传了条码 这时候验证是否要工作
                if (StartUploadCode == false)
                {
                    LogWithUi($"在{CurrentStationName}收到上传条码命令变为false", StationRecordData.AbsScanCode);
                    WriteData(StationConfig.EndUploadCodeAddr, 0, StationRecordData.AbsScanCode);
                    WriteData(StationConfig.AllowWorkAddr, 0, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}复位工作控制指令和复位上传条码完成指令", StationRecordData.AbsScanCode);

                    WriteData(StationConfig.PrintRltAddr, 0, StationRecordData.AbsScanCode);//清空PLC打标标记
                    LogWithUi($"在{CurrentStationName}打标记录,clear", StationRecordData.AbsScanCode);
                }
                else
                {
                    LogWithUi($"在{CurrentStationName}收到上传条码信息命令", StationRecordData.AbsScanCode);

                    #region 验证缸体码是否合格
                    LogWithUi($"在{CurrentStationName}工位检查缸体码是否合格", StationRecordData.AbsScanCode);
                    var codeRes = base.MainCodeVerify(StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}工位检查缸体码是否合格{StationRecordData.AbsScanCode}的结论是{codeRes}", StationRecordData.AbsScanCode);
                    if (!codeRes) {
                        LogWithUi($"在{CurrentStationName}工位检查缸体码不合格", StationRecordData.AbsScanCode);
                        var writeRlt0 = WriteWorkActionToPlc(StationConfig.AllowWorkAddr, WorkActionEnum.CodeErr, StationRecordData.AbsScanCode);
                        LogWithUi($"在{CurrentStationName}工位向下位机下发消息，下发{writeRlt0}", StationRecordData.AbsScanCode);
                        return;
                    }
                    #endregion

                    LogWithUi($"在{CurrentStationName}工位结论验证,条码信息是{StationRecordData.AbsScanCode}", StationRecordData.AbsScanCode);
                    var validataRlt = Validata(CurrentStationName, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}工位的验证结果是{validataRlt}", StationRecordData.AbsScanCode);
                    var writeRlt = WriteWorkActionToPlc(StationConfig.AllowWorkAddr, validataRlt, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}工位向下位机下发消息，下发{writeRlt}", StationRecordData.AbsScanCode);
                }
                return;
            }


            if (signalName == nameof(StartUploadData))
            {
                if (StartUploadData)
                {
                    //todo 上传数据 这时候将数据记录到数据库中
                    LogWithUi($"在{CurrentStationName}收到上传记录数据命令", StationRecordData.AbsScanCode);
                    var rlt = RecordData();
                    WriteData(StationConfig.EndUploadDataAddr, (short)rlt, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}数据记录,rlt={rlt}", StationRecordData.AbsScanCode);
                    if (StationRecordData.Result == _okCode && rlt == 1)
                    {
                        LogWithUi($"在{CurrentStationName}数据记录完成,打印标签开始1", StationRecordData.AbsScanCode);
                        PrintLabel();
                        LogWithUi($"在{CurrentStationName}数据记录完成,打印标签完成1", StationRecordData.AbsScanCode);
                    }
                }
                else
                {
                    LogWithUi($"在{CurrentStationName}收到上传记录数据命令变为false", StationRecordData.AbsScanCode);

                    WriteData(StationConfig.EndUploadDataAddr, 0, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}数据记录,clear", StationRecordData.AbsScanCode);
                }
            }


            #region 查重验证
            if (signalName == nameof(RepeatCheckSignal))
            {
                if (RepeatCheckSignal)
                {
                    LogWithUi($"在{CurrentStationName}收到查重条码信息命令，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    if (AppSession.Config.IsEnabledScanCodeCheckRepeatVerify)
                    {
                        var repeatlist = _mainDbOperate.GetModelList<AbsPrintResult>(o => o.AbsCode == ScanQrCode1 && o.Code == ScanQrCode2);
                        if (repeatlist == null || repeatlist.Count == 0)
                        {
                            repeatlist = _mainDbOperate.GetModelList<AbsPrintResult>(o => o.AbsCode == ScanQrCode2 && o.Code == ScanQrCode1);
                        }
                        var rlt = (repeatlist.Count == 1);
                        WriteData("DB99.102", (rlt == true ? (short)1 : (short)2), $"ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                        LogWithUi($"在{CurrentStationName}查重条码信息完成，结果：{rlt}，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    }
                    else
                    {
                        LogWithUi($"在{CurrentStationName}收到查重条码信息命令，结果：【未启用】，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    }
                }
                else
                {
                    LogWithUi($"在{CurrentStationName}收到查重条码信息命令变为false，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    WriteData("DB99.102", 0, $"ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                }
            }
            #endregion

        }

        public override int RecordData() {
            var result = new QOP050RStationResult() {
                StationCode = base.StationConfig.StationCode,
                AbsScanCode = StationRecordData.AbsScanCode,
                Code = StationRecordData.Code,
                CycleTime = StationRecordData.CycleTime,
                Result = StationRecordData.Result,
                PartType = StationRecordData.PartType,
                PressForce = StationRecordData.PressForce,
                PressPosition = StationRecordData.PressPosition,
                ThreadLength = StationRecordData.ThreadLength,
                TightenAngle = StationRecordData.TightenAngle,
                TightenTorque = StationRecordData.TightenTorque,
                CreateTime = DateTime.Now,
                ProductID = Cache.CurWorkProduct.Id,
                //以下是批次追溯
                LabelCapScanCode = StationRecordData.LabelCapScanCode,
                DustCapScanCode = StationRecordData.DustCapScanCode,
            };
            var writeRlt = false;
            if (_mainDbOperate.CheckExist<QOP050RStationResult>(p => p.AbsScanCode == result.AbsScanCode && !result.IsReworked)) {
                var beforeRlt = _mainDbOperate.GetModel<QOP050RStationResult>(p => p.AbsScanCode == result.AbsScanCode && !result.IsReworked);
                result.Id = beforeRlt.Id;
                writeRlt = _mainDbOperate.UpdateModelSuper<QOP050RStationResult>(p => p.AbsScanCode == result.AbsScanCode && !result.IsReworked, result);
                LogWithUi($"在{CurrentStationName}工位数据更新,rlt={writeRlt}", StationRecordData.AbsScanCode);
            } else {
                writeRlt = _mainDbOperate.AddModel(result);
                LogWithUi($"在{CurrentStationName}工位数据新增,rlt={writeRlt}", StationRecordData.AbsScanCode);
            }
            return writeRlt ? 1 : 2;
        }


        protected override WorkActionEnum Validata(string currentStation, string code, string[] stations = null) {
            var stationIndex = Cache.WorkStationValidationList.IndexOf(currentStation);
            if (stationIndex == -1) {
                return WorkActionEnum.NoEnable;
            }
            if (stationIndex > 0) {
                //检测上一个站
                var beforeStationName = Cache.WorkStationValidationList[stationIndex - 1];

                if (beforeStationName == "OP580-1") {
                    var stationLIndex = Cache.WorkStationValidationList.IndexOf("OP580-1");
                    if (stationLIndex == 0) {
                        //上个工位是L工位，只验证是否在R工位是否做过

                        //检查当前工位
                        LogWithUi($"在{currentStation}工位不存在上个工位，检查在本工位工作结论", code);
                        var checkResult = CheckCodeExistAndResult(currentStation, code);
                        if (checkResult == 1) {
                            return WorkActionEnum.HasWorkInCurrent;
                        } else {
                            return WorkActionEnum.StartWork;
                        }
                    } else {
                        beforeStationName = Cache.WorkStationValidationList[stationLIndex - 1];
                    }
                }

                LogWithUi($"在{currentStation}工位上一个启动的检查工位是{beforeStationName}", code);
                var checkRlt = CheckCodeExistAndResult(beforeStationName, code);
                LogWithUi($"在{beforeStationName}工位检查{code}的结论是{checkRlt}", code);
                if (checkRlt == 1) {
                    LogWithUi($"在上个工位{beforeStationName}工位检查{code}的结论是{checkRlt},开始检查是否在本工位{currentStation}结论", code);
                    var currentResult = CheckCodeExistAndResult(currentStation, code);
                    LogWithUi($"在本工位{currentStation}工位检查{code}的结论是{currentResult}", code);
                    if (currentResult == 1) {
                        return WorkActionEnum.HasWorkInCurrent;
                    } else {
                        return WorkActionEnum.StartWork;
                    }
                } else if (checkRlt == 2) {
                    return WorkActionEnum.WorkNgInBefore;
                } else {
                    return WorkActionEnum.NotWorkInBefore;
                }
            } else {
                //检查当前工位
                LogWithUi($"在{currentStation}工位不存在上个工位，检查在本工位工作结论", code);
                var checkResult = CheckCodeExistAndResult(currentStation, code);
                if (checkResult == 1) {
                    return WorkActionEnum.HasWorkInCurrent;
                } else {
                    return WorkActionEnum.StartWork;
                }
            }
        }

        private void PrintLabel() {

            var temp = _mainDbOperate.GetModel<TemplateEntity>(o => o.ProductID == Cache.CurWorkProduct.Id && o.TemplateType == eTemplateType.LabelCode);
            if (temp != null) {
                try {

                    var barCode = StationRecordData.AbsScanCode;
                    var printParams = base.GeneratePrintParams(temp, ePrintStartionCode.Q_OP580_2, barCode);

                    //打印成功，将数据打印的数据记录到关联表中
                    var printRecord = new AbsPrintResult() {
                        Brand = Cache.CurWorkProduct.CustomerName,
                        Model = Cache.CurWorkProduct.Model,
                        AbsCode = StationRecordData.AbsScanCode,
                        Code = printParams.qrCode,
                        PrintTime = DateTime.Now,
                        LeftRight = (int)Cache.CurWorkProduct.WorkDirection,
                        ProductID = Cache.CurWorkProduct.Id,
                        PrintParams = JsonConvert.SerializeObject(printParams.printParams),
                    };
                    var isAddSuccess = _mainDbOperate.AddModel(printRecord);
                    var isUpdateSuccess = _mainDbOperate.UpdateModel<QOP050RStationResult>(p => p.AbsScanCode == printRecord.AbsCode && !p.IsReworked, p => new QOP050RStationResult { Code = printParams.qrCode });

                    if (isAddSuccess && isUpdateSuccess) {

                        LogWithUi($"在{CurrentStationName}开始打印工件标签，模板是【${temp.TemplatePath}】", barCode);
                        LogWithUi($"在{CurrentStationName}打印第【{printParams.curIndex}】个工件、标签码【{printParams.qrCode}】下发打印任务完成", barCode);

                        _printerService.PrintLabel(temp.TemplatePath, StationConfig.PrinterName, printParams.qrCode, printParams.printParams, absScanCode: barCode);

                        //同步到老系统表
                        ProductIndexHelper.SynchronizeToOldSystemIndex(Cache.CurWorkProduct, ePrintStartionCode.Q_OP580_2);

                        _ = Task.Run(() => {
                            _mainDbOperate.UpdateModel<QOP006StationResult>(p => p.AbsScanCode == printRecord.AbsCode && !p.IsReworked, p => new QOP006StationResult { Code = printParams.qrCode });
                            _mainDbOperate.UpdateModel<QOP010StationResult>(p => p.AbsScanCode == printRecord.AbsCode && !p.IsReworked, p => new QOP010StationResult { Code = printParams.qrCode });
                            _mainDbOperate.UpdateModel<QOP020StationResult>(p => p.AbsScanCode == printRecord.AbsCode && !p.IsReworked, p => new QOP020StationResult { Code = printParams.qrCode });
                        });

                        LogWithUi($"在{CurrentStationName}打印成功", barCode);
                        WriteData(StationConfig.PrintRltAddr, 1, barCode);

                    } else {
                        LogWithUi($"在{CurrentStationName}打印失败，失败原因：记录打印结果到数据库失败", barCode);
                        WriteData(StationConfig.PrintRltAddr, 2, barCode);
                    }

                } catch (Exception ex) {
                    LogWithUi($"在{CurrentStationName}打印失败,失败原因{ex.Message}", StationRecordData.AbsScanCode);
                    WriteData(StationConfig.PrintRltAddr, 2);
                }

                GetCurrentLableIndex(ePrintStartionCode.Q_OP580_2);
            }
        }

    }


}
